/**
 * $Id: liveprOverlay.js,v 1.11 2006/11/08 14:14:07 peter Exp $
 *
 * Script to load LivePR value for current URL and display on statusbar.
 * This script is part of the LivePR Firefox Extension.
 * It is licensed under the GPL. 
 * More details on <http://livepr.raketforskning.com/>.
 */

/** */
function hexdec(str) {
    return parseInt(str,16);
}

/** */
function zeroFill(a,b) {
    var z = hexdec(80000000);
    if (z & a) {
        a = a>>1;
        a &= ~z;
        a |= 0x40000000;
        a = a>>(b-1);
    } else {
        a = a >> b;
    }
    return (a);
}

/** */
function mix(a,b,c) {
    a -= b; a -= c; a ^= (zeroFill(c,13));
    b -= c; b -= a; b ^= (a<<8);
    c -= a; c -= b; c ^= (zeroFill(b,13));
    a -= b; a -= c; a ^= (zeroFill(c,12));
    b -= c; b -= a; b ^= (a<<16);
    c -= a; c -= b; c ^= (zeroFill(b,5));
    a -= b; a -= c; a ^= (zeroFill(c,3));
    b -= c; b -= a; b ^= (a<<10);
    c -= a; c -= b; c ^= (zeroFill(b,15));
    var ret = new Array((a),(b),(c));
    return ret;
}

/** */
function GoogleCH(url) {
    var init = 0xE6359A60;
    var length = url.length;   
    var a = 0x9E3779B9;
    var b = 0x9E3779B9;
    var c = 0xE6359A60;
    var k = 0;
    var len = length;
    var mixo = new Array();
    while (len >= 12) {
        a += (url[k+0] +(url[k+1]<<8) +(url[k+2]<<16) +(url[k+3]<<24));
        b += (url[k+4] +(url[k+5]<<8) +(url[k+6]<<16) +(url[k+7]<<24));
        c += (url[k+8] +(url[k+9]<<8) +(url[k+10]<<16)+(url[k+11]<<24));
        mixo = mix(a,b,c);
        a = mixo[0]; b = mixo[1]; c = mixo[2];
        k += 12;
        len -= 12;
    }
    c += length;
    switch(len)
    {
        case 11:
        c += url[k+10]<<24;
        case 10:
        c+=url[k+9]<<16;
        case 9 :
        c+=url[k+8]<<8;
        case 8 :
        b+=(url[k+7]<<24);
        case 7 :
        b+=(url[k+6]<<16);
        case 6 :
        b+=(url[k+5]<<8);
        case 5 :
        b+=(url[k+4]);
        case 4 :
        a+=(url[k+3]<<24);
        case 3 :
        a+=(url[k+2]<<16);
        case 2 :
        a+=(url[k+1]<<8);
        case 1 :
        a+=(url[k+0]);
    }
    mixo = mix(a,b,c);
//    if (mixo[2] < 0)
//        return (0x100000000 + mixo[2]);
//    else
    return mixo[2];
}

/** */
function strord(string) {
    var result = new Array();
    for (var i = 0; i < string.length; ++i) {
        result[i] = string[i].charCodeAt(0);
    }
    return result;
}

/** */
function c32to8bit(arr32) {
    var arr8 = new Array();	
    for (var i = 0; i < arr32.length; ++i) {
    	for (bitOrder = i*4; bitOrder <= i*4+3; ++bitOrder) {
            arr8[bitOrder] = arr32[i]&255;
            arr32[i] = zeroFill(arr32[i], 8);
        }
    }
    return arr8;
}

/** */
function myfmod(x,y) {
	var i = Math.floor(x/y);
    return (x - i*y);
}

/** */
function GoogleNewCH(url) {
    var ch = "6"+GoogleCH(strord(url));
    return ch;
}

/** */
function cleanURL(str) {
    return str.replace("http://", "");
}

var prefix;

/** Set LivePR value. */
function setLivePR() {
    var livepr = document.getElementById('livepr-status');
    var tooltip = document.getElementById('livepr-tooltip-value');
    var tmp = liveprreq.responseText;
    if (tmp.length == 0) return;

    var data = tmp.split(/\n/);
    var results_pr = new Array();
    var results_url = new Array();
    // Extract relevant data.
    if (prefix == "info:") {
        for (var i = 0; i < data.length; ++i) {
            var m = data[i].match(/^Rank_\d+:\d+:(\d+)/);
            if (m) {
                results_pr[1] = m[1];
            }
            if (m = data[i].match(/^URL_\d+:\d+:(.+)/)) {
                results_url[1] = m[1];
            }
        }
        if (results_pr[1]) {
            pr = results_pr[1];
        } else {
            pr = -1;
        }
    } else {
        for (var i = 0; i < data.length; ++i) {
            // Get level.
            var m = data[i].match(/^Level_(\d+):/);
            if (m) {
                // Group this entry.
                var level = m[1];
                while (data[i] != "") {
                    if ((m = data[i].match(/^Rank_\d+:\d+:(\d+)/))) {
                        results_pr[level] = m[1];
                    }
                    if ((m = data[i].match(/^URL_\d+:\d+:(.+)/))) {
                        results_url[level] = m[1];
                    }
                    ++i;
                }
            }
        }
        // Create url permutations.
        var url = new String(window._content.document.location);
        var nonwwwurl = url.replace('www.', '');
        var urlpermutations = new Array(url,
                                        "http://"+url, 
                                        "http://www."+url, 
                                        url+"/", 
                                        "http://"+url+"/", 
                                        "http://www."+url+"/", 
                                        nonwwwurl, 
                                        "http://"+nonwwwurl, 
                                        "http://www."+nonwwwurl, 
                                        nonwwwurl+"/", 
                                        "http://"+nonwwwurl+"/", 
                                        "http://www."+nonwwwurl+"/");
        // Fish out PR.
        var pr = -1;
        for (var i = 1; i < results_url.length; ++i) {
            if (pr != -1) break;
            for (var j = 0; j < urlpermutations.length; ++j) {
                if (urlpermutations[j].toLowerCase() == results_url[i].toLowerCase()) {
                    pr = results_pr[i];
                    break;
                }
            }
        }
    }
    // ToolTip text.
    var tt = (pr >= 0 && pr <= 10) ? pr+"/10" : "N/A";

    livepr.setAttribute("livepr", pr);
    tooltip.setAttribute("value", "PageRank: "+tt);
    liveprLastPR = pr;
}

/** Encode a URL. */
function URLencode(sStr) {
    //enc = encodeURIComponent(sStr).replace(/\+/g,"%2B").replace(/\//g,"%2F");
    return sStr;
}

/** Initialize LivePR. */
function initLivePR() {
    var livepr = document.getElementById('livepr-status');
    var tooltip = document.getElementById('livepr-tooltip-value');
    
    var url = new String(window._content.document.location);
    //url = url.replace(/\?.*$/g,'?');
    //var datacenter = "dc.livepr.raketforskning.com";
    var datacenter = "toolbarqueries.google.com";

    //prefix = "allinurl:";
    prefix = "info:";
    var reqgr = prefix + url;
    var reqgre = prefix + cleanURL(url);
    var feat = "";
    if (prefix == "info:") {
        feat = "Rank";
    }
    var gch = GoogleNewCH(reqgre);

    var querystring = "http://"+datacenter+"/search?client=navclient-auto&ch="+gch+"&features="+feat+"&q="+reqgre+"&num=100&filter=0";

    var pattern1 = /^http:/;
    var pattern2 = /^http:\/\/.*google\..*\/(search|images|groups|news).*/;
    var pattern3 = /^http:\/\/localhost.*/;
    var pattern4 = /^http:\/\/(127\.|10\.|172\.16|192\.168).*/; //local ip
    var pattern5 = /^about:/;

    if (!lprenabled) { 
        // Do nothing.
    } else if (!pattern1.test(url) || 
        pattern2.test(url) ||
        pattern3.test(url) || 
        pattern4.test(url) ||
        pattern5.test(url)) {
        livepr.setAttribute("livepr", -1);
        tooltip.setAttribute("value", "PageRank: N/A");
        liveprLastPR = -1;
    } else {
        //dump("\n"+querystring+"\n");
        
        liveprreq = new XMLHttpRequest();
        liveprreq.onload = setLivePR;
        liveprreq.open("GET", querystring);
        liveprreq.setRequestHeader("User-Agent","Mozilla/4.0 (compatible; GoogleToolbar 2.0.114-big; Windows XP 5.1)");
        liveprreq.send(null);
    }
    liveprLastURL = GoogleNewCH(url);
}

/** Reset LivePR. */
function resetLivePR() {
    var livepr = document.getElementById('livepr-status');
    var tooltip = document.getElementById('livepr-tooltip-value');
    var url = new String(window._content.document.location);
    
    //url = url.replace(/\?.*$/g,'?');
    if (!lprenabled) {
        livepr.setAttribute("livepr", "disabled");
        tooltip.setAttribute("value", "Disabled");
    } else if (GoogleNewCH(url) == liveprLastURL) {
        livepr.setAttribute("livepr", liveprLastPR);
        if (liveprLastPR == -1) {
            tooltip.setAttribute("value", "PageRank: N/A");
        } else {
            tooltip.setAttribute("value", "PageRank: "+liveprLastPR);
        }
    } else {
        liveprLastURL = GoogleNewCH(url);
        initLivePR();
    }
}

/** Switch state. Controlled by popup menu. */
function switchliveprstate(event) {
    const LEFT = 0;
    var tooltip = document.getElementById('livepr-tooltip-value');
    var livepr = document.getElementById('livepr-status');
    var menuitem = document.getElementById('livepr-main-menu-state');

    if (event.button == LEFT) {
        if (!lprenabled) {
            gLivePRPref.setIntPref("state", 1);
            lprenabled = 1;
            initLivePR();
        } else {
            gLivePRPref.setIntPref("state", 0);
            lprenabled = 0;
            livepr.setAttribute("livepr", "disabled");
            tooltip.setAttribute("value", "Disabled");
        }
        liveprSavePreferences();
    }
}

function liveprAboutDialog() {
    window.open('chrome://livepr/content/about.xul','','chrome,centerscreen');
}

function liveprGoURL(url) {
    window.open(url);
}

function liveprSavePreferences() {
    // Enabled/disabled?
    try {
        gLivePRPref.setIntPref("state", lprenabled);
    }
    catch (err) {
        dump("\nSetting preference for state failed: " + err + "\n");
    }

    // Position
    try {
        gLivePRPref.setCharPref("parent_element_id", gLivePRParentElementID);
    }
    catch (err) {
        dump("\nSetting preference for parent_element_id failed: " + err + "\n");
    }
    try {
        gLivePRPref.setCharPref("insert_before_element_id", gLivePRInsertBeforeElementId);
    }
    catch (err) {
        dump("\nSetting preference for insert_before_element_id failed: " + err + "\n");
    }
    try {
        gLivePRPref.setCharPref("insert_after_element_id", gLivePRInsertAfterElementId);
    }
    catch (err) {
        dump("\nSetting preference for insert_after_element_id failed: " + err + "\n");
    }

    // Save settings.
    try {
        gLivePRPrefService.savePrefFile(null);
    }
    catch (err) {
        dump("\nSaving preferences failed: " + err + "\n");
    }
    //dump("Preferences saved.\n");
}

function liveprLoadPreferences() {
    try {
        lprenabled = gLivePRPref.getIntPref("state");
    }
    catch (err) {
        lprenabled = 1;
    }
    try {
        gLivePRParentElementID = gLivePRPref.getCharPref("parent_element_id");
    }
    catch (err) {
        gLivePRParentElementID = '';
    }
    try {
        gLivePRInsertBeforeElementId = gLivePRPref.getCharPref("insert_before_element_id");
    }
    catch (err) {
        gLivePRInsertBeforeElementId = '';
    }
    try {
        gLivePRInsertAfterElementId = gLivePRPref.getCharPref("insert_after_element_id");
    }
    catch (err) {
        gLivePRInsertAfterElementId = '';
    }
    //dump("Preferences loaded. Applying preferences.\n");
    liveprSetLivePRPosition();
}

/** Preferences */
var gLivePRPrefService = Components.classes["@mozilla.org/preferences-service;1"]
                         .getService(Components.interfaces.nsIPrefService);
var gLivePRPref = gLivePRPrefService.getBranch("livepr.");

/** Vars */
var lprenabled;
var liveprreq;
var liveprLastURL;
var liveprLastPR;

/** Listeners */
window.addEventListener("load",function() {liveprLoadPreferences(); initLivePR();},true);
window.addEventListener("focus",function() {resetLivePR();},true); 
